package com.emeraldparser.grammar;

import com.emeraldparser.symbol.SymbolClass;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;

public final class NewRule {

	private final ImmutableList<? extends SymbolClass> leftHandSide;
	private final ImmutableList<? extends SymbolClass> rightHandSide;
	private final transient int hashCode;

	public NewRule(Iterable<? extends SymbolClass> leftHandSide, Iterable<? extends SymbolClass> rightHandSide) {
		this(ImmutableList.copyOf(leftHandSide), ImmutableList.copyOf(rightHandSide));
	}

	public NewRule(ImmutableList<? extends SymbolClass> leftHandSide, ImmutableList<? extends SymbolClass> rightHandSide) {
		this.leftHandSide = Preconditions.checkNotNull(leftHandSide, "Left hand side must not be null");
		this.rightHandSide = Preconditions.checkNotNull(rightHandSide, "Right hand side must not be null");
		this.hashCode = Objects.hashCode(leftHandSide, rightHandSide);
	}

	public ImmutableList<? extends SymbolClass> getLeftHandSide() {
		return leftHandSide;
	}

	public ImmutableList<? extends SymbolClass> getRightHandSide() {
		return rightHandSide;
	}

	@Override
	public String toString() {
		return leftHandSide + " = " + rightHandSide;
	}

	@Override
	public int hashCode() {
		return hashCode;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		
		if (obj == null) {
			return false;
		}
		
		if (getClass() != obj.getClass()) {
			return false;
		}
		
		NewRule other = (NewRule) obj;
		return Objects.equal(leftHandSide, other.leftHandSide)
		    && Objects.equal(rightHandSide, other.rightHandSide);
	}

}
